﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;

namespace Yorrick.FlickrMetadataSynchr.Match
{
    /// <summary>
    /// Structure that holds a match key that is the combination of the date taken and the title/filename.
    /// </summary>
    internal struct DateTakenTitleMatchKey: IEquatable<DateTakenTitleMatchKey>
    {
        #region Private fields
        /// <summary>
        /// The date taken.
        /// </summary>
        private DateTime _dateTaken;

        /// <summary>
        /// The title.
        /// </summary>
        private string _title;

        /// <summary>
        /// The key that determines object identity and equality.
        /// </summary>
        private string _key;
        #endregion

        #region Constructor
        /// <summary>
        /// Constructs a new instance.
        /// </summary>
        /// <param name="dateTaken">The date taken.</param>
        /// <param name="title">The title.</param>
        public DateTakenTitleMatchKey(DateTime dateTaken, string title)
        {
            _dateTaken = dateTaken;

            if (title == null)
            {
                _title = "";
            }
            else
            {
                _title = title;
            }

            _key = null;
        }
        #endregion

        #region Private methods
        /// <summary>
        /// Ensures that the key that determines the object identity is initialized.
        /// </summary>
        private void EnsureKey()
        {
            if (_key == null)
            {
                _key = _dateTaken.ToString("s", CultureInfo.InvariantCulture) + "|" + _title;
            }
        }
        #endregion

        #region Public properties
        /// <summary>
        /// Gets the date taken.
        /// </summary>
        public DateTime DateTaken
        {
            get
            {
                return _dateTaken;
            }
        }

        /// <summary>
        /// Gets the title.
        /// </summary>
        public string Title
        {
            get
            {
                return _title;
            }
        }
        #endregion

        #region Public methods
        /// <summary>
        /// Determines if this instance is equal to the object provided.
        /// </summary>
        /// <param name="obj">The object to compare to.</param>
        /// <returns><c>True</c> if equal, <c>false</c> otherwise.</returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }

            DateTakenTitleMatchKey key2 = (obj as DateTakenTitleMatchKey?).Value;

            return Equals(key2);
        }

        /// <summary>
        /// Determines if this instance is equal to the instance provided.
        /// </summary>
        /// <param name="key2">The instance to compare to.</param>
        /// <returns><c>True</c> if equal, <c>false</c> otherwise.</returns>
        public bool Equals(DateTakenTitleMatchKey key2)
        {
            EnsureKey();
            key2.EnsureKey();

            return (this._key == key2._key);
        }

        /// <summary>
        /// Returns the hash code for this instance.
        /// </summary>
        /// <returns>The hash code for this instance.</returns>
        public override int GetHashCode()
        {
            EnsureKey();

            return _key.GetHashCode();
        }

        /// <summary>
        /// Returns a human readable version of this instance of this structure.
        /// </summary>
        /// <returns>A a human readable version of this structure.</returns>
        public override string ToString()
        {
            EnsureKey();

            return _key;
        }
        #endregion

        #region IEquatable<DateTakenTitleMatchKey> Members

        #endregion
    }
}
